"""
在 Python 中，变量的作用域和访问控制是通过命名约定来实现的。Python 并没有像其他一些语言（如 Java 或 C++）
那样提供严格的访问修饰符（如 public、protected 和 private），但可以通过命名约定来模拟这些访问控制。

总结：
- 全局变量：在函数外部定义的变量，可以在整个模块中访问。使用 global 关键字可以在函数内部声明一个全局变量。
- 受保护的属性：以单个下划线 _ 开头的变量或方法，表示该属性或方法是受保护的，不应该在类的外部直接访问。这是一种约定，而不是强制性的。
- 私有属性：以双下划线 __ 开头的变量或方法，表示该属性或方法是私有的，不应该在类的外部直接访问。Python 会通过名称改写机制来防止直接访问这些属性。
"""
# 1. 全局变量
x = 10  # 全局变量


def my_function():
    global x  # 声明 x 是全局变量
    x = 20  # 修改全局变量 x 的值
    print(f"Inside function: x = {x}")


my_function()
print(f"Outside function: x = {x}")


# 2. 受保护的属性(proteced)
class MyClass:
    def __init__(self):
        self._protected_var = 10  # 受保护的属性

    def _protected_method(self):
        print("This is a protected method")


obj = MyClass()
print(obj._protected_var)  # 可以访问，但不推荐
obj._protected_method()  # 可以调用，但不推荐


# 3. 私有属性
class MyClass:
    def __init__(self):
        self.__private_var = 10  # 私有属性

    def __private_method(self):
        print("This is a private method")

    def public_method(self):
        self.__private_method()  # 可以在类内部访问


obj = MyClass()

# 尝试直接访问私有属性
try:
    print(obj.__private_var)  # 会引发 AttributeError
except AttributeError as e:
    print(e)

# 尝试直接调用私有方法
try:
    obj.__private_method()  # 会引发 AttributeError
except AttributeError as e:
    print(e)

# 通过名称改写访问私有属性
print(obj._MyClass__private_var)  # 10
obj._MyClass__private_method()  # This is a private method

# 通过公共方法访问私有方法
obj.public_method()  # This is a private method
